package cn.hftoday.core;

import java.util.*;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import cn.hftoday.util.*;

/**
 * Client/Server communication package
 * @author lane.cn@gmail.com
 *
 */
public class Package {
	private int code;
	private String result;
	private String message;
	private HashMap<String, String> map = new HashMap<String, String>();
	
	/**
	 * constructor
	 */
	public Package()
	{
	}
	
	/**
	 * constructor
	 * @param xml
	 */
	public Package(String xml)
	{
		setXml(xml);
	}
	
	/*
	 * package code
	 */
	public int getCode() {
		return code;
	}

	/**
	 * package code
	 * @param code
	 */
	public void setCode(int code) {
		this.code = code;
	}
	
	/**
	 * result(ok/ng)
	 * @return
	 */
	public String getResult() {
		return result;
	}
	
	/**
	 * result(ok/ng)
	 * @param result
	 */
	public void setResult(String result) {
		this.result = result;
	}
	
	/**
	 * exception message
	 * @return
	 */
	public String getMessage() {
		return message;
	}
	
	/**
	 * exception message
	 * @param message
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * get attribute
	 * @param key
	 * @return
	 */
	public String getAttribute(String key) {
		return map.get(key).toString();
	}
	
	/**
	 * set attribute
	 * @param key
	 * @param value
	 */
	public void setAttribute(String key, String value) {
		map.put(key, value);
	}
	
	/**
	 * get xml message
	 * @return
	 */
	public String getXml() {
		//head
		StringBuilder xml = new StringBuilder("<?xml version=\"1.0\"?>");
		xml.append("<root><head><code>");
		xml.append(code);
		xml.append("</code><ret>");
		xml.append(result.toLowerCase());
		xml.append("</ret><msg>");
		if (message != null)
			xml.append(message);
		xml.append("</msg></head><body>");
		
		//body
		Iterator<String> keys = map.keySet().iterator();
		while (keys.hasNext()) {
			String key = keys.next().toString();
			String value = map.get(key).toString();
			xml.append("<v k=\"");
			xml.append(StringParser.parseXml(key));
			xml.append("\">");
			xml.append(StringParser.parseXml(value));
			xml.append("</v>");
		}
		
		//tail
		xml.append("</body></root>");
		return xml.toString();
	}
	
	/**
	 * set xml message
	 * @param xml
	 */
	public void setXml(String xml) {
		DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
		Document doc = null;
		try {
			DocumentBuilder dombuilder = domfac.newDocumentBuilder();
			StringReader reader = new StringReader(xml);
			InputSource is = new InputSource(reader);
			doc = dombuilder.parse(is);
		}
		catch (Exception e) {
			throw new RuntimeException("error.bad.package", e);
		}
		
		try {
			Element rootNode = doc.getDocumentElement();
			
			//code
			NodeList codeNodeList = rootNode.getElementsByTagName("code");
			Element codeNode = (Element)codeNodeList.item(0);
			code = Integer.parseInt(codeNode.getTextContent());
			
			//result
			NodeList retNodeList = rootNode.getElementsByTagName("ret");
			Element retNode = (Element)retNodeList.item(0);
			result = retNode.getTextContent();
			
			//message
			NodeList msgNodeList = rootNode.getElementsByTagName("msg");
			Element msgNode = (Element)msgNodeList.item(0);
			message = msgNode.getTextContent();
			
			//attributes
			NodeList vNodeList = rootNode.getElementsByTagName("v");
			for (int i = 0; i < vNodeList.getLength(); i ++) {
				Element vNode = (Element)vNodeList.item(i);
				String k = vNode.getAttribute("k");
				String v = vNode.getTextContent();
				map.put(k, v);
			}
		}
		catch (Exception e) {
			throw new RuntimeException("error.package.parser", e);
		}
	}
}
